package com.tunnel.client.tcp;

import java.util.LinkedList;
import java.util.List;

import com.tunnel.common.util.LogUtil;

/**
 * tunnel 数据管道
 * 阻塞队列，消费者模式
 */
public class TcpDataQueue {

	//*****************双队列，读写分离*******************//
	//使用LinkedQuee，因为考虑吞吐速度可以慢一点，但是对空间利用率希望好一些
	private List<TcpData> READ_QUEUE = new LinkedList<>();
	private List<TcpData> WRITE_QUEUE = new LinkedList<>();
	private static final int QUEUE_SIZE = 500;//队列长度500，这样可以减少最长的等待延迟
	//*****************

	private volatile boolean stop = false;
	
	public void stop(){
		synchronized (READ_QUEUE) {
			synchronized (WRITE_QUEUE) {
				READ_QUEUE.clear();
				WRITE_QUEUE.clear();
			}
		}
		stop = true;
	}

	public void startQueue(){
		new Thread("TcpDataQueue"){
			public void run() {
				while(!stop){
					try {
						synchronized (READ_QUEUE) {
							if(READ_QUEUE.size() > 0){
								TcpData data = READ_QUEUE.remove(0);
								boolean sendSuccess = data.getTask().sendData2App(data.getDatas());
								if(!sendSuccess && !data.getTask().isStop()){
									for(int i=0;i<10&&!sendSuccess;i++){
										Thread.sleep(1000);
										//尝试10次发送，如果还不行，就结束
										sendSuccess = data.getTask().sendData2App(data.getDatas());
									}
								}
							}else{
								Thread.sleep(1);//防止cpu饱和
								synchronized (WRITE_QUEUE) {
									if(READ_QUEUE.size() == 0 && WRITE_QUEUE.size() > 0){
//											LogUtil.log("交换RW队列0->"+WRITE_QUEUE.size());
										List<TcpData> tmpQueue = WRITE_QUEUE;
										WRITE_QUEUE = READ_QUEUE;
										READ_QUEUE = tmpQueue;
									}
								}
							}
						}
					} catch (Exception e) {
						LogUtil.error(e);
					}
				}
//				LogUtil.log("队列结束");
			};
		}.start();
	}
	
	public boolean addDataToQueue(TcpData data){
		synchronized (WRITE_QUEUE) {
			if(WRITE_QUEUE.size() >= QUEUE_SIZE){
				return false;
			}
			WRITE_QUEUE.add(data);
			return true;
		}
	}
}
